using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Terminal.Advanced_AEUC_settings_controls.Settings_Interfaces;
using Terminal.Advanced_AEUC_settings_controls.Settings_AUX;
using Terminal.Advanced_AEUC_settings_controls.Settings_Editing_Forms;

namespace Terminal.Advanced_AEUC_settings_controls.Setting_Advanced_Control
{
    /// <summary>
    /// A composete user control that holds an extended combo box (AEUC Setting modded) and its label
    /// </summary>
    public partial class AEUCComboBox : UserControl, IAEUCSetting, IAEUCEnumeration, IAEUCSerialization
    {
        const int AEUC_CB_SIZE = 90;
        const int AEUC_LBL_LOC = 99;

        AEUCSettingComboBox AEUC_CB;
        Label lblName;

        #region Constructors
        /// <summary>
        /// Public constructor of the composite user control
        /// </summary>
        public AEUCComboBox()
        {
            //InitializeComponent();
            AEUC_CB = new Terminal.Advanced_AEUC_settings_controls.Setting_Advanced_Control.AEUCSettingComboBox();
            lblName = new System.Windows.Forms.Label();

            AEUC_CB.Location = new System.Drawing.Point(3, 3);
            AEUC_CB.Size = new System.Drawing.Size(90, 21);
            AEUC_CB.Parent = this;

            lblName.AutoSize = true;
            lblName.Location = new System.Drawing.Point(99, 6);
            lblName.Size = new System.Drawing.Size(35, 13);
            lblName.Parent = this;

            Size = new System.Drawing.Size(3 + AEUC_CB.Size.Width + 3 + lblName.Size.Width, 3 + AEUC_CB.Size.Height);

            AEUC_CB.GotFocus +=new EventHandler(AEUC_CB_GotFocus);
            AEUC_CB.MouseClick +=new MouseEventHandler(AEUC_CB_MouseClick);

            AEUC_DisplayName = AEUC_DisplayName;
        }
        /// <summary>
        /// Public constructor of the composite user control
        /// </summary>
        /// <param name="iID">Setting ID</param>
        /// <param name="iSize">Setting size</param>
        /// <param name="iVal">Current value</param>
        /// <param name="iDefVal">Default value</param>
        /// <param name="iMinVal">Minimum value</param>
        /// <param name="iMaxVal">Maximum value</param>
        public AEUCComboBox(uint iID, uint iSize, Int64 iVal, Int64 iDefVal, Int64 iMinVal, Int64 iMaxVal)
        {
            AEUC_CB = new Terminal.Advanced_AEUC_settings_controls.Setting_Advanced_Control.AEUCSettingComboBox(iID,iSize,iVal,iDefVal,iMinVal,iMaxVal);
            lblName = new System.Windows.Forms.Label();

            AEUC_CB.Location = new System.Drawing.Point(3, 3);
            AEUC_CB.Size = new System.Drawing.Size(90, 21);
            AEUC_CB.Parent = this;

            lblName.AutoSize = true;
            lblName.Location = new System.Drawing.Point(99, 6);
            lblName.Size = new System.Drawing.Size(35, 13);
            lblName.Parent = this;

            Size = new System.Drawing.Size(3 + AEUC_CB.Size.Width + 3 + lblName.Size.Width, 3 + AEUC_CB.Size.Height);

            AEUC_CB.GotFocus +=new EventHandler(AEUC_CB_GotFocus);
            AEUC_CB.MouseClick +=new MouseEventHandler(AEUC_CB_MouseClick);

            AEUC_DisplayName = AEUC_DisplayName;
        }
        /// <summary>
        /// Public constructor of the composite user control
        /// </summary>
        /// <param name="iID">Setting ID</param>
        /// <param name="iSize">Setting size</param>
        /// <param name="iVal">Current value</param>
        /// <param name="iDefVal">Default value</param>
        /// <param name="iMinVal">Minimum value</param>
        /// <param name="iMaxVal">Maximum value</param>
        /// <param name="iEnabled">Setting enabled</param>
        /// <param name="iStateSense">Track state changes</param>
        /// <param name="iAux">Use only as uaxiliary control</param>
        /// <param name="iDisplayName">String display name</param>
        public AEUCComboBox(uint iID, uint iSize, Int64 iVal, Int64 iDefVal, Int64 iMinVal, Int64 iMaxVal, bool iEnabled, bool iStateSense, bool iAux, string iDisplayName)
        {
            AEUC_CB = new Terminal.Advanced_AEUC_settings_controls.Setting_Advanced_Control.AEUCSettingComboBox(iID,iSize,iVal,iDefVal,iMinVal,iMaxVal,iEnabled,iStateSense,iAux,iDisplayName);
            lblName = new System.Windows.Forms.Label();

            AEUC_CB.Location = new System.Drawing.Point(3, 3);
            AEUC_CB.Size = new System.Drawing.Size(90, 21);
            AEUC_CB.Parent = this;

            lblName.AutoSize = true;
            lblName.Location = new System.Drawing.Point(99, 6);
            lblName.Size = new System.Drawing.Size(35, 13);
            lblName.Parent = this;

            Size = new System.Drawing.Size(3 + AEUC_CB.Size.Width + 3 + lblName.Size.Width, 3 + AEUC_CB.Size.Height);

            AEUC_CB.GotFocus +=new EventHandler(AEUC_CB_GotFocus);
            AEUC_CB.MouseClick +=new MouseEventHandler(AEUC_CB_MouseClick);

            AEUC_DisplayName = AEUC_DisplayName;
        }
        #endregion

        /// <summary>
        /// When the child AEUC setting control receives focus, fire the focus event of the user composite control, so it acts transperantly
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Event arguments</param>
        void AEUC_CB_GotFocus(object sender, EventArgs e)
        {
            OnGotFocus(e);
        }
        /// <summary>
        /// When the child AEUC setting control fires mouse click, fire the mouse click event of the user composite control, so it acts transperantly
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Event arguments</param>
        void AEUC_CB_MouseClick(object sender, MouseEventArgs e)
        {
            OnMouseClick(e);
        }
        /// <summary>
        /// When the child AEUC changes its combo box selection list resize to fit the new environment
        /// </summary>
        void AEUC_CB_OnEnumCollectionUpdate()
        {
            ReSizeComboBox();
        }
        /// <summary>
        /// Updates the visible name and the length of the control accordingly
        /// </summary>
        /// <param name="iname">The new displayed control name</param>
        public void CC_Update_UI_Name(string iname)
        {
            lblName.Text = iname;
            Size = new Size(lblName.Location.X + lblName.Size.Width, Size.Height);
        }
        /// <summary>
        /// Upscales the control so that every enumeration item can be seen as a whole in the dropdown list
        /// </summary>
        void ReSizeComboBox()
        {
            Graphics gfx = CreateGraphics();
            SizeF tmpStringMeasure = new SizeF(0, 0);

            foreach (GenAEUCEnumerationItem enVal in AEUC_CB.Items)
            {
                if (tmpStringMeasure.Width < gfx.MeasureString(enVal.AEUC_displayname, AEUC_CB.Font).Width)
                    tmpStringMeasure = gfx.MeasureString(enVal.AEUC_displayname, AEUC_CB.Font);
            }

            int szOfst = (int)tmpStringMeasure.Width + 10 - AEUC_CB.Size.Width;
            if (szOfst > 0)
            {
                lblName.Location = new Point(lblName.Location.X + szOfst, lblName.Location.Y);
                AEUC_CB.Size = new Size((int)tmpStringMeasure.Width + 10, AEUC_CB.Size.Height);
            }
            else if (szOfst < 0)
            {
                lblName.Location = new Point(AEUC_LBL_LOC, lblName.Location.Y);
                AEUC_CB.Size = new Size(AEUC_CB_SIZE, AEUC_CB.Size.Height);
            }

            CC_Update_UI_Name(lblName.Text);
        }
        /// <summary>
        /// Start up control scaling service
        /// </summary>
        public void InitSizingWatch()
        {
            AEUC_CB.OnEnumCollectionUpdate += new AEUCSettingComboBox.EnumCollectionUpdate(AEUC_CB_OnEnumCollectionUpdate);
            ReSizeComboBox();
        }
        /// <summary>
        /// Overrrided ToString method
        /// </summary>
        /// <returns>Underlying AEUC_CB instance name</returns>
        public override string ToString()
        {
            return AEUC_CB.AEUC_DisplayName;
        }

        #region IAEUCSetting Members
        /// <summary>
        /// Get or set the AEUC-Setting primary value
        /// </summary>
        public Int64 AEUC_Val
        {
            get
            {
                return AEUC_CB.AEUC_Val;
            }
            set
            {
                AEUC_CB.AEUC_Val = value;
            }
        }
        /// <summary>
        /// Get or set the AEUC-Setting optional value
        /// </summary>
        public Int64 AEUC_OptVal
        {
            get
            {
                return AEUC_CB.AEUC_OptVal;
            }
            set
            {
                AEUC_CB.AEUC_OptVal = value;
            }
        }
        /// <summary>
        /// Get or set the AEUC-Setting default value
        /// </summary>
        public Int64 AEUC_Default
        {
            get
            {
                return AEUC_CB.AEUC_Default;
            }
            set
            {
                AEUC_CB.AEUC_Default = value;
            }
        }
        /// <summary>
        /// Get or set the AEUC-Setting minimum value
        /// </summary>
        public Int64 AEUC_Min
        {
            get
            {
                return AEUC_CB.AEUC_Min;
            }
            set
            {
                AEUC_CB.AEUC_Min = value;
            }
        }
        /// <summary>
        /// Get or set the AEUC-Setting maximum value
        /// </summary>
        public Int64 AEUC_Max
        {
            get
            {
                return AEUC_CB.AEUC_Max;
            }
            set
            {
                AEUC_CB.AEUC_Max = value;
            }
        }
        /// <summary>
        /// Get or set the AEUC-Setting id
        /// </summary>
        public uint AEUC_Id
        {
            get
            {
                return AEUC_CB.AEUC_Id;
            }
            set
            {
                AEUC_CB.AEUC_Id = value;
            }
        }
        /// <summary>
        /// Get or set the AEUC-Setting size
        /// </summary>
        public uint AEUC_Size
        {
            get
            {
                return AEUC_CB.AEUC_Size;
            }
            set
            {
                AEUC_CB.AEUC_Size = value;
            }
        }
        /// <summary>
        /// Get or set current availability of this control
        /// </summary>
        public bool AEUC_Enabled
        {
            get
            {
                return AEUC_CB.AEUC_Enabled;
            }
            set
            {
                AEUC_CB.AEUC_Enabled = value;
            }
        }
        /// <summary>
        /// Reference pointer
        /// </summary>
        public bool AEUC_RefPointer
        {
            get
            {
                return AEUC_CB.AEUC_RefPointer;
            }
            set
            {
                AEUC_CB.AEUC_RefPointer = value;
            }
        }
        /// <summary>
        /// Set or get current support for state change sense
        /// </summary>
        public bool AEUC_SupportStateSense
        {
            get
            {
                return AEUC_CB.AEUC_SupportStateSense;
            }
            set
            {
                AEUC_CB.AEUC_SupportStateSense = value;
            }
        }
        /// <summary>
        /// Raise the state change flag
        /// </summary>
        public void AEUC_SetStateChange(bool do_itter)
        {
            AEUC_CB.AEUC_SetStateChange(do_itter);
        }
        /// <summary>
        /// Set the reset the state of the control
        /// </summary>
        public void AEUC_ResetToDefault()
        {
            AEUC_CB.AEUC_ResetToDefault();
        }
        /// <summary>
        /// Composes a generic AEUC-Setting
        /// </summary>
        /// <returns>A generic AEUC-Setting representation</returns>
        public GenAEUCSetting AEUC_GetSetting()
        {
            return AEUC_CB.AEUC_GetSetting();
        }
        /// <summary>
        /// Gets or sets the link status of the control
        /// </summary>
        public bool AEUC_LinkedSetting
        {
            get
            {
                return AEUC_CB.AEUC_LinkedSetting;
            }
            set
            {
                AEUC_CB.AEUC_LinkedSetting = value;
            }
        }
        /// <summary>
        /// Get or set the next control in the link chain, null if none
        /// </summary>
        public IAEUCSetting AEUC_NextSettingLink
        {
            get
            {
                return AEUC_CB.AEUC_NextSettingLink;
            }
            set
            {
                AEUC_CB.AEUC_NextSettingLink = value;
            }
        }
        /// <summary>
        /// Get or set the type of the control link chain
        /// </summary>
        public int AEUC_SettingChainType
        {
            get
            {
                return AEUC_CB.AEUC_SettingChainType;
            }
            set
            {
                AEUC_CB.AEUC_SettingChainType = value;
            }
        }
        /// <summary>
        /// Get or set the auxiliary status of the setting
        /// </summary>
        public bool AEUC_AUXSetting
        {
            get
            {
                return AEUC_CB.AEUC_AUXSetting;
            }
            set
            {
                AEUC_CB.AEUC_AUXSetting = value;
            }
        }
        /// <summary>
        /// Get or set the control linked to the primary value of this auxiliary setting
        /// </summary>
        public IAEUCSetting AEUC_SettingPrimaryLink
        {
            get
            {
                return AEUC_CB.AEUC_SettingPrimaryLink;
            }
            set
            {
                AEUC_CB.AEUC_SettingPrimaryLink = value;
            }
        }
        /// <summary>
        /// Get or set the control linked to the secondary value of this auxiliary setting
        /// </summary>
        public IAEUCSetting AEUC_SettingSecondaryLink
        {
            get
            {
                return AEUC_CB.AEUC_SettingSecondaryLink;
            }
            set
            {
                AEUC_CB.AEUC_SettingSecondaryLink = value;
            }
        }
        /// <summary>
        /// Restore the setting value to its shadowed copy
        /// </summary>
        public void AEUC_RestoreShadowedValue()
        {
            AEUC_CB.AEUC_RestoreShadowedValue();
        }
        /// <summary>
        /// Update the shadowed copy of a setting to its new value
        /// </summary>
        public void AEUC_UpdateShadowedValue()
        {
            AEUC_CB.AEUC_UpdateShadowedValue();
        }
        /// <summary>
        /// Get or set the use of shadowed copy for this settig
        /// </summary>
        public bool AEUC_ShadowedValue
        {
            get
            {
                return AEUC_CB.AEUC_ShadowedValue;
            }
            set
            {
                AEUC_CB.AEUC_ShadowedValue = value;
            }
        }
        /// <summary>
        /// Get or set the display string of the control
        /// </summary>
        public string AEUC_DisplayName
        {
            get
            {
                return AEUC_CB.AEUC_DisplayName;
            }
            set
            {
                AEUC_CB.AEUC_DisplayName = value;
                CC_Update_UI_Name(AEUC_CB.AEUC_DisplayName);
            }
        }
        /// <summary>
        /// When the control array is deserialized from a stream, this function will set the appropirate control links
        /// </summary>
        /// <returns>True if the operation completed successfully</returns>
        public bool AEUC_SetLinkInitialization()
        {
            return AEUC_CB.AEUC_SetLinkInitialization();
        }
        /// <summary>
        /// Returns the reference to the valid AEUC setting object
        /// </summary>
        /// <returns>vali AEUC setting object</returns>
        public IAEUCSetting AEUC_GetLinkReference()
        {
            return AEUC_CB.AEUC_GetLinkReference();
        }
        /// <summary>
        /// Recursive itteration in the linked group to obtain a composite value
        /// </summary>
        /// <returns>Integer value</returns>
        public Int64 AEUC_LinkValueAgregation()
        {
            return AEUC_CB.AEUC_LinkValueAgregation();
        }
        /// <summary>
        /// Recursive itteration in the linked group to set a composite value
        /// </summary>
        /// <returns>Integer value</returns>
        public void AEUC_LinkValueSetValue(Int64 l_val)
        {
            AEUC_CB.AEUC_LinkValueSetValue(l_val);
        }
        #endregion

        #region IAEUCEnumeration Members
        /// <summary>
        /// Adds an enumeration item to the item array of the control
        /// </summary>
        /// <param name="iDisplay">Display string of the item</param>
        /// <param name="iVal">Primary value</param>
        /// <param name="iOptVal">Optional value</param>
        public void AEUC_AddEnumVal(string iDisplay, Int64 iVal, Int64 iOptVal)
        {
            AEUC_CB.AEUC_AddEnumVal(iDisplay, iVal, iOptVal);
        }
        /// <summary>
        /// Deletes an enumeration value at the specified position
        /// </summary>
        /// <param name="iPosition">The position in the item array</param>
        public void AEUC_DeleteEnumVal(int iPosition)
        {
            AEUC_CB.AEUC_DeleteEnumVal(iPosition);
        }
        /// <summary>
        /// Returns an enumeration item from the specified position
        /// </summary>
        /// <param name="iPosition">the position within the item array</param>
        /// <returns></returns>
        public GenAEUCEnumerationItem AEUC_GetEnumVal(int iPosition)
        {
            return AEUC_CB.AEUC_GetEnumVal(iPosition);
        }
        /// <summary>
        /// Changes the values of an enummeration item at a specific position
        /// </summary>
        /// <param name="iPosition">The position within the item array</param>
        /// <param name="iDisplayName">New display name</param>
        /// <param name="iVal">New primary value</param>
        /// <param name="iOptVal">New optional value</param>
        public void AEUC_EditEnumVal(int iPosition, string iDisplayName, Int64 iVal, Int64 iOptVal)
        {
            AEUC_CB.AEUC_EditEnumVal(iPosition, iDisplayName, iVal, iOptVal);
        }
        #endregion

        #region IAEUCSerialization Members
        /// <summary>
        /// Current element serialization state version
        /// </summary>
        public int serVersion
        {
            get
            {
                return 0x000;
            }
        }
        /// <summary>
        /// Saves this objec instance to a file
        /// </summary>
        /// <param name="srWriter">Binray writer of the associated file</param>
        public void Serialize(System.IO.BinaryWriter srWriter)
        {
            srWriter.Write(serVersion);
            Serialize_v000(srWriter);
        }
        /// <summary>
        /// Loads this objects instance from a file
        /// </summary>
        /// <param name="srReader">Binray reader of the associated file</param>
        /// <returns>Boolean representing the success of the operation</returns>
        public bool Deserialize(System.IO.BinaryReader srReader)
        {
            bool desProcState;
            int serialVer = srReader.ReadInt32();

            switch (serialVer)
            {
                case 0x000:
                    desProcState = Deserialize_v000(srReader);
                    break;
                default:
                    desProcState = false;
                    break;
            }

            return desProcState;
        }

        #region Version 0x000 serialization
        /// <summary>
        /// Version 0x000 serialization
        /// </summary>
        /// <param name="srWriter">File writer</param>
        void Serialize_v000(System.IO.BinaryWriter srWriter)
        {
            srWriter.Write(Location.X);
            srWriter.Write(Location.Y);

            AEUC_CB.Serialize(srWriter);
        }
        /// <summary>
        /// Version 0x000 deserialization
        /// </summary>
        /// <param name="srReader">File reader</param>
        /// <returns>True if operation is succesful</returns>
        bool Deserialize_v000(System.IO.BinaryReader srReader)
        {
            Location = new System.Drawing.Point(srReader.ReadInt32(), srReader.ReadInt32());

            bool op_stat = AEUC_CB.Deserialize(srReader);

            AEUC_CB.Location = new System.Drawing.Point(3, 3);
            AEUC_CB.Size = new System.Drawing.Size(90, 21);
            AEUC_CB.Parent = this;

            AEUC_DisplayName = AEUC_DisplayName;

            return op_stat;
        }
        #endregion
        #endregion
    }
}
